package org.programmers.anonymous.fightrobots.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

import com.fasterxml.jackson.annotation.JsonIgnore;


public class Robot implements IRobot, Comparable<Robot> {
	
	protected int idRobot = -99;
	protected String name = "Empty";
	protected int life = 100;
	protected Status currentStatus = Status.READY;
	protected Action currentAction = null;
	protected List<IWeapon> robotWeaponList  = new ArrayList<IWeapon>();
	protected List<IDeffense> robotDeffenseList  = new ArrayList<IDeffense>();
	protected int aggressivity = 50;
	protected IWeapon currentWeapon = null;
	protected IDeffense currentDeffense = null;
	
	
	
	
	@Override
	public int getIdRobot(){
		return idRobot;
	}
	
	@Override
	public void setIdRobot(int idRobot){
		this.idRobot = idRobot;
	}

	@Override
	public String getName() {
		return name;
	}

	@Override
	public void setName(String n) {
		this.name=n;
	}

	@Override
	public int getLife() {
		return life;
	}

	@Override
	public void setLife(int l) {
		this.life = l;
	}

	@Override
	public List<IWeapon> getRobotWeaponList() {
		return robotWeaponList;
	}
	
	public void setRobotWeaponList(List<IWeapon> weaponList)
	{
		this.robotWeaponList = weaponList;
	}

	@Override
	public List<IDeffense> getRobotDeffenseList() {
		return robotDeffenseList;
	}
	
	public void setRobotDeffenseList(List<IDeffense> deffenseList)
	{
		this.robotDeffenseList = deffenseList;
	}

	@Override
	public void addWeaponIntoRobotList(IWeapon w) {
		this.robotWeaponList.add(w);
	}

	@Override
	public void addDeffenseIntoRobotList(IDeffense d) {
		this.robotDeffenseList.add(d);
	}
	
	@Override
	public Status getCurrentStatus() {
		return currentStatus;
	}
	
	@Override
	public void setCurrentStatus(Status status) {
		this.currentStatus = status;
	}
	
	 @JsonIgnore
	@Override
	public Action getRandomAction() 
	{
		setRandomAction();
		return currentAction;
	}
	
	@Override
	public Action getCurrentAction() 
	{
		return currentAction;
	}

	private boolean setCurrentDeffense()
	{
		boolean isEmpty = false;
		if (this.currentDeffense == null || this.currentDeffense.getHits() <= 0)
		{
			for(IDeffense d: robotDeffenseList){
				if(d.getHits()>0){
					this.currentDeffense = d;
					break;
				}else{
					this.currentDeffense = robotDeffenseList.get(0);
					isEmpty = true;
				}
			}
		}
		return isEmpty;
	}

	private boolean setCurrentWeapon()
	{
		boolean isEmpty = false;
		if (this.currentWeapon == null || this.currentWeapon.getHits() <= 0)
		{
			for(IWeapon w: robotWeaponList){
				if(w.getHits()>0){
					this.currentWeapon = w;
					break;
				}else{
					this.currentWeapon = robotWeaponList.get(0);
					isEmpty = true;
				}
			}
		}
		return isEmpty;
	}

	private void setRandomAction() {
		
		Random r = new Random();
		int num =r.nextInt(101);
		
		if(num <= aggressivity)
		{
			setCurrentWeapon();
			this.currentAction= Action.ATTACK;
			this.currentWeapon.setHits((this.currentWeapon.getHits()-1));
		}
		else
		{
			setCurrentDeffense();
			this.currentAction = Action.DEFFENSE;
			this.currentDeffense.setHits(this.currentDeffense.getHits()-1);
		}
	}
	
	public void setAction(Action action)
	{
		if(action == Action.ATTACK)
		{
			setCurrentWeapon();
		} 
		else 
		{
			setCurrentDeffense();
		}

		this.currentAction = action;
	}
	
	@Override
	public int getAggressivity() {
		return aggressivity;
	}

	@Override
	public void setAggressivity(int aggressivity) {
		this.aggressivity = aggressivity;
	}
	
	public IWeapon getCurrentWeapon() {
		return currentWeapon;
	}
	
	public void setCurrentWeapon(IWeapon currentWeapon) {
		this.currentWeapon = currentWeapon;
	}
	
	public IDeffense getCurrentDeffense() {
		return currentDeffense;
	}
	
	public void setCurrentDeffense(IDeffense currentDeffense) {
		this.currentDeffense = currentDeffense;
	}

	/*
	 * (non-Javadoc)
	 * @see org.programmers.anonymous.fightrobots.model.IRobot#getEquipmentId(org.programmers.anonymous.fightrobots.model.IRobot.Action)
	 */
	@JsonIgnore
	@Override
	public int getCurrentEquipmentId() {
		if (this.currentAction == Action.ATTACK)
		{
			return this.currentWeapon.getIdWeapon();
		}
		else if (this.currentAction == Action.DEFFENSE)
		{
			return this.currentDeffense.getIdDeffense();
		}else
		{
			//TODO:If the current action is not an Attack or a Deffense
			return -99;
		}
	}
	
	@JsonIgnore
	@Override
	public int getCurrentEquipmentHits() {
		if (this.currentAction == Action.ATTACK)
		{
			return this.currentWeapon.getHits();
		}
		else if (this.currentAction == Action.DEFFENSE)
		{
			return this.currentDeffense.getHits();
		}else
		{
			//TODO:If the current action is not an Attack or a Deffense
			return -99;
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.programmers.anonymous.fightrobots.model.IRobot#getEquipmentValue(int)
	 */
	@JsonIgnore
	@Override
	public int getCurrentEquipmentValue() {
		
		if (this.currentAction == Action.ATTACK)
		{
			return this.currentWeapon.getPower();
		}
		else if (this.currentAction == Action.DEFFENSE)
		{
			return this.currentDeffense.getPower();
		}else
		{
			//TODO:If the current action is not an Attack or a Deffense
			return -99;
		}
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.programmers.anonymous.fightrobots.model.IRobot#compareTo(org.programmers.anonymous.fightrobots.model.Robot)
	 */
	@Override
	public int compareTo(Robot r) {		
		
		if( this.getName().compareTo(r.getName()) != 0){	
			return this.getName().compareTo(r.getName());			
		}else if (this.getLife() != r.getLife()){
			return (this.getLife() - r.getLife())/Math.abs((this.getLife() - r.getLife()));
		}else if (this.getAggressivity() != r.getAggressivity()){			
			return (this.getAggressivity() - r.getAggressivity())/Math.abs((this.getAggressivity() - r.getAggressivity()));
		}else return 0;
	}
	
	@Override
	public boolean equals(Object obj )
	{
		if (obj == null)
            return false;
        if (obj == this)
            return true;
        if (!(obj instanceof Robot))
            return false;

        Robot r = (Robot) obj;
        
        return new EqualsBuilder().
                // if deriving: appendSuper(super.equals(obj)).
                append(name, r.name).
                isEquals();
        /*
		if(this.getName().equalsIgnoreCase(r.getName()))
		{
			return true;
		}
		else
		{
			return false;
		}
		*/
	}
	
	@Override
	 public int hashCode() {
	        return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
	            // if deriving: appendSuper(super.hashCode()).
	            append(name).
	            toHashCode();
	}


	@Override
	public String toString() {
		StringBuffer strBuffer = new StringBuffer();
		strBuffer.append("[Robot id: ");
		strBuffer.append(this.getIdRobot());		
		strBuffer.append("; name: ");
		strBuffer.append(this.getName());			
		strBuffer.append("; weapons: ");	
		if(this.getRobotWeaponList() != null) strBuffer.append(this.getRobotWeaponList().size());		
		strBuffer.append("; deffenses: ");	
		if(this.getRobotDeffenseList() != null) strBuffer.append(this.getRobotDeffenseList().size());
		strBuffer.append("; aggressivity: ");
		strBuffer.append(this.getAggressivity());
		strBuffer.append("; life: ");
		strBuffer.append(this.getLife());
		strBuffer.append("; STATUS: ");
		strBuffer.append(this.getCurrentStatus());
		strBuffer.append("]");
		
		return strBuffer.toString();
	}

	 @JsonIgnore
	@Override
	public boolean getNewEquipment() {
		boolean isEmpty = false;
		
		if(currentAction == Action.ATTACK)
		{
			isEmpty = setCurrentWeapon();
			return isEmpty;
		} 
		else 
		{
			isEmpty = setCurrentDeffense();
			return isEmpty;
		}
	}
}
